﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Dokan
{
	public abstract class AbstractOperations : DokanOperations
	{
		/// <summary>
		/// Creates or opens a file or I/O device.
		/// </summary>
		///<remarks>
		/// http://127.0.0.1:47873/help/1-5816/ms.help?method=page&id=80A96083-4DE9-4422-9705-B8AD2B6CBD1B&product=VS&productversion=100&locale=en-US&format=html&topicVersion=85&topicLocale=EN-US&embedded=true
		/// 
		/// Creates or opens a file or I/O device. The most commonly used I/O
		/// devices are as follows: file, file stream, directory, physical
		/// disk, volume, console buffer, tape drive, communications resource,
		/// mailslot, and pipe.
		/// </remarks>
		/// <param name="filename">The name of the file or device to be created or opened.</param>
		/// <param name="access"><see cref="System.IO.FileAccess"/></param>
		/// <param name="share"><see cref="System.IO.FileShare"/></param>
		/// <param name="mode"><see cref="System.IO.FileMode"/></param>
		/// <param name="options"><see cref="System.IO.FileOptions"/></param>
		/// <param name="info"><see cref="DokanFileInfo"/></param>
		/// <returns>A Windows error code, or 0 on no error.</returns>
		public abstract int CreateFile(string filename, System.IO.FileAccess access, System.IO.FileShare share, System.IO.FileMode mode, System.IO.FileOptions options, DokanFileInfo info);
		/// <summary>
		/// Opens a directory.
		/// </summary>
		/// <param name="filename">The directory name passed.</param>
		/// <param name="info"><see cref="DokanFileInfo"/></param>
		/// <returns>a Windows error code, or 0 on no error.</returns>
		public abstract int OpenDirectory(string filename, DokanFileInfo info);
		/// <summary>
		/// Creates a new directory.
		/// </summary>
		/// <param name="filename">The new directory's name.</param>
		/// <param name="info"><see cref="DokanFileInfo"/></param>
		/// <returns>a Windows error code, or 0 on no error.</returns>
		public abstract int CreateDirectory(string filename, DokanFileInfo info);
		/// <summary>
		/// Called by Dokan when a file is closed.
		/// </summary>
		/// <param name="filename">The name of the file that was closed.</param>
		/// <param name="info"><see cref="DokanFileInfo"/></param>
		/// <returns>A Windows error code, or 0 on success.</returns>
		public abstract int Cleanup(string filename, DokanFileInfo info);
		/// <summary>
		/// Called after Cleanup().
		/// </summary>
		/// <param name="filename">The filename which is being closed.</param>
		/// <param name="info"><see cref="DokanFileInfo"/></param>
		/// <returns>A Windows error code, or 0 on success.</returns>
		public abstract int CloseFile(string filename, DokanFileInfo info);
		/// <summary>
		/// Reads bytes from a file.
		/// </summary>
		/// <param name="filename">The name of the file to read from.</param>
		/// <param name="buffer">The buffer to read into.</param>
		/// <param name="readBytes">The number of bytes [i]to read/[o]actually read.</param>
		/// <param name="offset">The offset into the file to begin reading from.</param>
		/// <param name="info"><see cref="DokanFileInfo"/></param>
		/// <returns>A Windows error code, or 0 on success.</returns>
		public abstract int ReadFile(string filename, byte[] buffer, ref uint readBytes, long offset, DokanFileInfo info);
		/// <summary>
		/// Writes bytes to a file, starting at a given logical position.
		/// </summary>
		/// <param name="filename">The name of the file to write to.</param>
		/// <param name="buffer">The buffer containing the data to write.</param>
		/// <param name="writtenBytes">The number of bytes [i] to write/[o]actually written.</param>
		/// <param name="offset">The logical position to begin writing the buffer.</param>
		/// <param name="info"><see cref="DokanFileInfo"/></param>
		/// <returns>A Windows error code, or 0 on success.</returns>
		public abstract int WriteFile(string filename, byte[] buffer, ref uint writtenBytes, long offset, DokanFileInfo info);
		/// <summary>
		/// Causes any changed but unwritten data to be written to disk.
		/// </summary>
		/// <param name="filename">The name of the file to flush.</param>
		/// <param name="info"><see cref="DokanFileInfo"/></param>
		/// <returns>A Windows error code, or 0 on success.</returns>
		public abstract int FlushFileBuffers(string filename, DokanFileInfo info);
		/// <summary>
		/// Obtain filesystem information about the given file.
		/// </summary>
		/// <param name="filename">The name of the file to query.</param>
		/// <param name="fileinfo">The FileInformation structure to populate.</param>
		/// <param name="info">The <see cref="DokanFileInfo"/> describing this file.</param>
		/// <returns>A Windows error code, or 0 on success.</returns>
		public abstract int GetFileInformation(string filename, FileInformation fileinfo, DokanFileInfo info);
		/// <summary>
		/// Gets a list of files matching a given pattern.
		/// </summary>
		/// <param name="filename">The name of the file to query.</param>
		/// <param name="files">The <see cref="System.Collections.ArrayList"/>list of <see cref="DokanFileInfo"/> objects to populate.</param>
		/// <param name="info">The <see cref="DokanFileInfo"/> with the context to query.</param>
		/// <returns>A Windows error code, or 0 on success.</returns>
		public abstract int FindFiles(string filename, System.Collections.ArrayList files, DokanFileInfo info);
		/// <summary>
		/// Sets the filesystem attributes of the given file.
		/// </summary>
		/// <param name="filename">The name of the file which attributes to alter.</param>
		/// <param name="attr">The file's new attributes.</param>
		/// <param name="info">The <see cref="DokanFileInfo"/> which context the file exists within.</param>
		/// <returns>A Windows error code, or 0 on success.</returns>
		public abstract int SetFileAttributes(string filename, System.IO.FileAttributes attr, DokanFileInfo info);
		/// <summary>
		/// Sets the file's creation, access, and modification times.
		/// </summary>
		/// <param name="filename">The filename to work on.</param>
		/// <param name="ctime">The file's new creation time.</param>
		/// <param name="atime">The file's new access time.</param>
		/// <param name="mtime">The file's new modification time.</param>
		/// <param name="info">The <see cref="DokanFileInfo"/> with the context to work in.</param>
		/// <returns>A Windows error code, or 0 on success.</returns>
		public abstract int SetFileTime(string filename, DateTime ctime, DateTime atime, DateTime mtime, DokanFileInfo info);
		/// <summary>
		/// Deletes a file.
		/// </summary>
		/// <param name="filename">The name of the file to delete.</param>
		/// <param name="info">The <see cref="DokanFileInfo"/> within which to delete.</param>
		/// <returns>A Windows error code, or 0 on success.</returns>
		public abstract int DeleteFile(string filename, DokanFileInfo info);
		/// <summary>
		/// Removes a directory.  The directory must be empty.
		/// </summary>
		/// <param name="filename">The name of the directory to delete.</param>
		/// <param name="info">The <see cref="DokanFileInfo"/> to remove the directory from.</param>
		/// <returns></returns>
		public abstract int DeleteDirectory(string filename, DokanFileInfo info);
		/// <summary>
		/// Renames a file.
		/// </summary>
		/// <param name="filename">The name of the file to change the name of.</param>
		/// <param name="newname">The new name of the file.</param>
		/// <param name="replace">If newname already exists, should this overwrite?</param>
		/// <param name="info">The <see cref="DokanFileInfo"/> within which to work.</param>
		/// <returns>A Windows error code, or 0 on success.</returns>
		public abstract int MoveFile(string filename, string newname, bool replace, DokanFileInfo info);
		/// <summary>
		/// Sets the length of a file, either extending or truncating it.
		/// </summary>
		/// <remarks>If this is used to extend a file, the file becomes sparse.</remarks>
		/// <param name="filename">The name of the file to set the length of.</param>
		/// <param name="length">The new length of the file.</param>
		/// <param name="info">The <see cref="DokanFileInfo"/> against which to match the filename.</param>
		/// <returns>A Windows error code, or 0 on success.</returns>
		public abstract int SetEndOfFile(string filename, long length, DokanFileInfo info);
		/// <summary>
		/// Alters the actual allocation for the file.
		/// </summary>
		/// <param name="filename">The name of the file to allocate.</param>
		/// <param name="length">The new length of the allocation.</param>
		/// <param name="info">The <see cref="DokanFileInfo"/> within which filename exists.</param>
		/// <returns>A Windows error code, or 0 on success.</returns>
		public abstract int SetAllocationSize(string filename, long length, DokanFileInfo info);
		/// <summary>
		/// Locks a specified range in the file.
		/// </summary>
		/// <param name="filename">The name of the file to lock some portion of.</param>
		/// <param name="offset">The beginning offset of the region to lock.</param>
		/// <param name="length">The length of the region to lock.</param>
		/// <param name="info">The <see cref="DokanFileInfo"/> within which to work.</param>
		/// <returns>A Windows error code, or 0 on success.</returns>
		public abstract int LockFile(string filename, long offset, long length, DokanFileInfo info);
		/// <summary>
		/// Unlocks the specified range in the file.
		/// </summary>
		/// <param name="filename">The name of the file to unlock some portion of.</param>
		/// <param name="offset">The beginning offset of the region to unlock.</param>
		/// <param name="length">The length of the region to unlock.</param>
		/// <param name="info">The <see cref="DokanFileInfo"/> within which to work.</param>
		/// <returns>A Windows error code, or 0 on success.</returns>
		public abstract int UnlockFile(string filename, long offset, long length, DokanFileInfo info);
		/// <summary>
		/// Gets the free space on the volume.
		/// </summary>
		/// <param name="freeBytesAvailable">out: The maximum allocation of a file just created.</param>
		/// <param name="totalBytes">out: The total usable size of the volume.</param>
		/// <param name="totalFreeBytes">out: The total free byte count.</param>
		/// <param name="info">The <see cref="DokanFileInfo"/> to query</param>
		/// <returns>A Windows error code, or 0 on success.</returns>
		public abstract int GetDiskFreeSpace(ref ulong freeBytesAvailable, ref ulong totalBytes, ref ulong totalFreeBytes, DokanFileInfo info);
		/// <summary>
		/// Unmounts the filesystem.
		/// </summary>
		/// <param name="info">The <see cref="DokanFileInfo"/> to unmount.</param>
		/// <returns>A Windows error code, or 0 on success.</returns>
		public abstract int Unmount(DokanFileInfo info);
	}
}
